﻿using System;
using System.Linq;

namespace Gabriel.Algoritimos
{
    public class Pilha
    {
        #region Private Members

        private int _tamMax;
        private int _top;
        private object[] _elementos;
        private int p;

        #endregion

        #region Public Members

        /// <summary>
        /// Objeto do topo da pilha
        /// </summary>
        public object Topo { get { return TopObject(); } }
        /// <summary>
        /// Indica quando a pilha esta vazia
        /// </summary>
        public bool Vazio { get { return PilhaVazia(); } }
        /// <summary>
        /// Indica quando a pilha esta cheia
        /// </summary>
        public bool Cheio { get { return PilhaChiea(); } }

        #endregion

        #region Public Methods
        /// <summary>
        /// Constructor 
        /// </summary>
        /// <param name="TamanhoMax">Tamanho maximo da pilha</param>
        public Pilha(int TamanhoMax)
        {
            _tamMax = TamanhoMax;
            _elementos = new object[TamanhoMax];
            _top = 0;
        }

        /// <summary>
        /// Retorna o objeto que esta no topo da pilha e o desempilha
        /// </summary>
        /// <returns>Objeto que estava no topo da pilha</returns>
        public object Pop()
        {
            if (PilhaVazia())
            {
                throw new Exception("Pilha Vazia");
            }
            else
            {
                return _elementos[--_top];
            }
        }

        /// <summary>
        /// Insere um objeto no topo da pilha
        /// </summary>
        /// <param name="o">Obejto que sera inserido na pilha</param>
        public void Push(object o)
        {
            if (PilhaChiea())
            {
                throw new Exception("Pilha Cheia");
            }
            else
            {
                _elementos[_top++] = o;
            }

        }
        #endregion

        #region Private Metodos 
        private bool    PilhaChiea()
        {
            if (_tamMax == _top)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private object TopObject()
        {
            if (PilhaVazia())
            {
                throw new Exception("pilha vazia");
            }
            else
            {
                return _elementos[_top-1];
            }
        }

        private bool PilhaVazia()
        {
            if (_top == 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion
    }
}